<!DOCTYPE html>
<html>
  <!-- 
    This page does not work with Safari 13.0.2 due to
    - top level await
    - nullish coalescing operator
    Use flow-old-browser.html instead.
   -->
  <head>
    <title>VexFlow Tests</title>
    <link rel="stylesheet" href="flow.css" type="text/css" media="screen" />
    <link rel="stylesheet" href="qunit/qunit.css" />
    <script src="qunit/qunit.js"></script>
    <meta charset="UTF-8" />
  </head>
  <body>
    <div style="text-align: center">
      <div id="qunit"></div>
      <div id="qunit-fixture"></div>
      <div>
        <h2>[ <a href="https://vexflow.com">Home</a> ] [ <a href="https://github.com/0xfe/vexflow">GitHub</a> ]</h2>
        <h3>
          See the: <a id="vex-src" target="_blank"></a>. Don't forget to run the
          <a href="https://github.com/0xfe/vexflow/wiki/Visual-Regression-Tests">Visual Regression Tests</a>!
        </h3>
      </div>
      <p>&nbsp;</p>
      <p>&nbsp;</p>
      <p class="vf-footer">
        [ <a href="https://vexflow.com">Home</a> ] [ <a href="https://github.com/0xfe/vexflow">GitHub</a> ] [
        <a href="https://muthanna.com/">0xfe</a> ]
      </p>
    </div>
    <script type="module">
      function loadScript(url) {
        return new Promise((resolve, reject) => {
          const script = document.createElement('script');
          script.onload = resolve;
          script.onerror = reject;
          script.src = url;
          document.getElementsByTagName('head')[0].appendChild(script);
        });
      }

      // Support a query param to choose which VexFlow version to load.
      // ver=(build/cjs | reference | releases/3.0.9 | etc...)
      // If omitted, `ver` defaults to 'build/cjs'.
      // ver can also specify a version hosted on unpkg.com / jsdelivr.com:
      // ver=unpkg@3.0.9     => https://unpkg.com/vexflow@3.0.9/releases/vexflow-debug.js
      // ver=unpkg@1.2.77    => https://unpkg.com/vexflow@1.2.77/releases/vexflow-debug.js
      // ver=jsdelivr@4.0.0  => https://cdn.jsdelivr.net/npm/vexflow@4.0.0/build/vexflow-debug.js
      // ver=jsdelivr@1.2.90 => https://cdn.jsdelivr.net/npm/vexflow@1.2.90/releases/vexflow-debug.js
      const queryParams = new URLSearchParams(location.search);
      // When flow.html is hosted on unpkg.com, the query string is not available.
      // Allow the user to specify some params via the # fragment identifier.
      let hashParams;
      if (location.hash.length > 0) {
        hashParams = new URLSearchParams(location.hash.substr(1));
      }
      const ver = queryParams.get('ver') ?? hashParams?.get('ver') ?? 'build/cjs';
      const useESM = queryParams.get('esm') === 'true' || hashParams?.get('esm') === 'true';

      let vexURL;
      let testsURL;
      let vexPlusTestsURL;
      let isVersionFourOrNewer = true;

      // Determine if we are loading VexFlow from a CDN.
      let cdnURLPath;
      if (ver.includes('unpkg')) {
        cdnURLPath = 'https://unpkg.com/';
      } else if (ver.includes('jsdelivr')) {
        cdnURLPath = 'https://cdn.jsdelivr.net/npm/';
      }
      // If we are loading from a CDN, build the URLs.
      if (typeof cdnURLPath !== 'undefined') {
        const version = ver.split('@')[1];
        if (parseFloat(version) < 4) {
          isVersionFourOrNewer = false;
          vexURL = `${cdnURLPath}vexflow@${version}/releases/vexflow-debug.js`;
          testsURL = `${cdnURLPath}vexflow@${version}/releases/vexflow-tests.js`;
        } else {
          // VexFlow 4 moved the build output from releases/ to build/.
          vexURL = `${cdnURLPath}vexflow@${version}/build/vexflow-debug.js`;
          vexPlusTestsURL = `${cdnURLPath}vexflow@${version}/build/vexflow-debug-with-tests.js`;
        }
      } else {
        // We are NOT loading from a CDN.
        // We are loading from the local filesystem (vexflow/build/ | vexflow/reference | vexflow/releases/).
        const path = ver;

        // file://.../vexflow/tests/flow.html?ver=releases/3.0.9
        if (path.startsWith('releases')) {
          const pathParts = path.split('/');
          const version = parseFloat(pathParts[1]);
          isVersionFourOrNewer = version >= 4;
        }
        // TODO RONYEH: For versions 4.0.0 or higher, we need to consider the cjs/ and esm/ directories.
        vexURL = '../' + path + '/vexflow-debug.js';
        testsURL = '../' + path + '/vexflow-tests.js';
        vexPlusTestsURL = '../' + path + '/vexflow-debug-with-tests.js';
      }

      // Display which VexFlow version we loaded.
      const srcLink = document.getElementById('vex-src');
      srcLink.href = vexURL;
      srcLink.innerText = `VexFlow Source [${ver}]`;

      let loadVexFlow;
      const isFileProtocol = location.protocol === 'file:';
      if (useESM && isFileProtocol) {
        console.warn('ES modules require a web server for testing!');
      }
      if (useESM && !isFileProtocol) {
        console.log('LOADING ESM: VexFlow >= 4.0.0');
        // This ESM branch only works if flow.html is accessed from a web server
        // (e.g., `npx http-server` and browse to http://127.0.0.1:8080/tests/flow.html).
        loadVexFlow = async () => {
          const module = await import('../build/esm/entry/vexflow-debug-with-tests.js');
          window.Vex = module.Vex;
        };
      } else if (isVersionFourOrNewer) {
        console.log('LOADING CJS: VexFlow >= 4.0.0');
        // When loading version >= 4.0.0, only load vexflow-debug-with-tests.js
        loadVexFlow = () => loadScript(vexPlusTestsURL);
      } else {
        console.log('LOADING CJS: VexFlow <= 3.0.9');
        // 3.0.9 depends on jQuery.
        await loadScript('https://code.jquery.com/jquery-3.6.0.slim.min.js');
        // 3.0.9 uses module.exports in tabstave_tests.js.
        window.module = {};

        // When loading versions <= 3.0.9, load vexflow-debug.js and then vexflow-tests.js
        loadVexFlow = () => loadScript(vexURL).then(() => loadScript(testsURL));
      }

      await loadVexFlow();

      const VF = Vex.Flow;

      // Versions 4.0.0 and newer have support for preloading web fonts.
      // Versions 3.0.9 and older do not support this feature.
      if (VF.Font.loadWebFonts) {
        await VF.Font.loadWebFonts();
        // Optional: view the loaded fonts.
        // await document.fonts.ready;
        // document.fonts.forEach((fontFace) => console.log(fontFace));
      }

      // Optionally specify the QUnit module or filter in the fragment identifier.
      if (hashParams) {
        if (hashParams.has('module')) {
          QUnit.urlParams.module = hashParams.get('module');
        }
        if (hashParams.has('filter')) {
          QUnit.config.filter = hashParams.get('filter');
        }
      }

      // Show only failed tests.
      QUnit.config.hidepassed = true;
      QUnit.config.noglobals = true;
      VF.Test.run();
    </script>
  </body>
</html>
